﻿package com.agileai.miscdp.hotweb.generator.standard;

import java.io.File;
import java.util.HashMap;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

import com.agileai.miscdp.MiscdpPlugin;
import com.agileai.miscdp.NoOpEntityResolver;
import com.agileai.miscdp.hotweb.domain.ResFileValueProvider;
import com.agileai.miscdp.hotweb.domain.standard.StandardFuncModel;
import com.agileai.miscdp.hotweb.generator.Generator;
import com.agileai.miscdp.util.MiscdpUtil;
import com.agileai.util.StringUtil;
import com.agileai.util.XmlUtil;
/**
 * 服务配置代码生成器
 */
public class SMServiceCfgGenerator implements Generator{
	private StandardFuncModel suFuncModel = null;
	private String configFile = null;
	private String encoding = "UTF-8";
	
	public void generate() {
		try {
	        SAXReader saxReader = new SAXReader();
	        saxReader.setEntityResolver(new NoOpEntityResolver());
	        saxReader.setIncludeExternalDTDDeclarations(false);
	        saxReader.setValidation(false);
	        
	        Document document = saxReader.read(new File(configFile));
	        generateStandardConfig(document);
	        if (suFuncModel.getResFileValueProvider() != null){
	        	generateResFileConfig(document);
	        }
	        XmlUtil.writeDocument(document, encoding, configFile);
		} catch (Exception e) {
			MiscdpPlugin.getDefault().logError(e.getLocalizedMessage(), e);
		}
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void generateStandardConfig(Document document){
        String serviceId = suFuncModel.getServiceId();
        String serviceTargetId = serviceId.substring(0,serviceId.length()-7)+"Target";
        
        HashMap xmlMap = new HashMap();
        xmlMap.put("s", "http://www.springframework.org/schema/beans");
        XPath serviceTargetPath = document.createXPath("//s:beans/s:bean[@id='"+serviceTargetId+"']");
        serviceTargetPath.setNamespaceURIs(xmlMap);
        Node serviceTargetNode = serviceTargetPath.selectSingleNode(document);
        if (serviceTargetNode != null){
        	serviceTargetNode.getParent().remove(serviceTargetNode);
        }
        Element beansElement = (Element)document.selectSingleNode("//beans");
        Element newServiceTarget = beansElement.addElement("bean");
        String implClassName = suFuncModel.getImplClassName();
        newServiceTarget.addAttribute("id",serviceTargetId);
        newServiceTarget.addAttribute("class",implClassName);
        newServiceTarget.addAttribute("parent","baseService");
        String tableName = suFuncModel.getTableName();
        String sqlNameSpace = MiscdpUtil.getValidName(tableName);
        newServiceTarget.addElement("property").addAttribute("name","sqlNameSpace")
        	.addAttribute("value",sqlNameSpace);
    	newServiceTarget.addElement("property").addAttribute("name","tableName")
			.addAttribute("value",tableName);
    	
        XPath servicePath = document.createXPath("//s:beans/s:bean[@id='"+serviceId+"']");
        servicePath.setNamespaceURIs(xmlMap);
        Node serviceNode = servicePath.selectSingleNode(document);
        if (serviceNode != null){
        	serviceNode.getParent().remove(serviceNode);
        }
        Element newService = beansElement.addElement("bean");
        newService.addAttribute("id",serviceId);
        newService.addAttribute("parent","transactionBase");
        newService.addElement("property").addAttribute("name","target").addAttribute("ref",serviceTargetId);
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void generateResFileConfig(Document document){
		String tableName = suFuncModel.getTableName();
        String serviceId = StringUtil.lowerFirst(MiscdpUtil.getValidName(tableName))+"ResourceUploadService";
        String serviceTargetId = serviceId.substring(0,serviceId.length()-7)+"Target";
        
        HashMap xmlMap = new HashMap();
        xmlMap.put("s", "http://www.springframework.org/schema/beans");
        XPath serviceTargetPath = document.createXPath("//s:beans/s:bean[@id='"+serviceTargetId+"']");
        serviceTargetPath.setNamespaceURIs(xmlMap);
        Node serviceTargetNode = serviceTargetPath.selectSingleNode(document);
        if (serviceTargetNode != null){
        	serviceTargetNode.getParent().remove(serviceTargetNode);
        }
        Element beansElement = (Element)document.selectSingleNode("//beans");
        Element newServiceTarget = beansElement.addElement("bean");
        String implClassName = "com.agileai.hotweb.bizmoduler.core.ResourceUploadServiceImpl";
        newServiceTarget.addAttribute("id",serviceTargetId);
        newServiceTarget.addAttribute("class",implClassName);
        newServiceTarget.addAttribute("parent","baseService");
        
        ResFileValueProvider resFileValueProvider = suFuncModel.getResFileValueProvider();
        String refTableName = resFileValueProvider.getTableName();
        String sqlNameSpace = MiscdpUtil.getValidName(refTableName);
        String bizIdField = resFileValueProvider.getBizIdField();
        String resIdField = resFileValueProvider.getResIdField();
        newServiceTarget.addElement("property").addAttribute("name","sqlNameSpace")
        	.addAttribute("value",sqlNameSpace);
    	newServiceTarget.addElement("property").addAttribute("name","tableName")
			.addAttribute("value",refTableName);
       	newServiceTarget.addElement("property").addAttribute("name","bizIdField")
    			.addAttribute("value",bizIdField);
       	newServiceTarget.addElement("property").addAttribute("name","resIdField")
    			.addAttribute("value",resIdField);
    	
        XPath servicePath = document.createXPath("//s:beans/s:bean[@id='"+serviceId+"']");
        servicePath.setNamespaceURIs(xmlMap);
        Node serviceNode = servicePath.selectSingleNode(document);
        if (serviceNode != null){
        	serviceNode.getParent().remove(serviceNode);
        }
        Element newService = beansElement.addElement("bean");
        newService.addAttribute("id",serviceId);
        newService.addAttribute("parent","transactionBase");
        newService.addElement("property").addAttribute("name","target").addAttribute("ref",serviceTargetId);
	}
	
	public void setConfigFile(String configFile) {
		this.configFile = configFile;
	}

	public void setFuncModel(StandardFuncModel suFuncModel) {
		this.suFuncModel = suFuncModel;
	}
}